﻿#include <vector>
using namespace std;

namespace Make3D{
    namespace core {

template <class T>
class InterpolatedArray{
        protected :
            virtual T interpolate(T a, T b, float x) = 0;

        private:
             vector<T> vertices;
             int out_points;

        public:
        InterpolatedArray(int interpolated_points) {
            out_points = interpolated_points;
        }

        InterpolatedArray(int interpolated_points, vector<T> &list) : (interpolated_points) {
            vertices = list;
        }

        const T operator[] (int index) const {
         if (vertices.size() == 0) throw "empty vector";
           else if (vertices.size() == 1) return vertices[0];

             float x = (float)index / (float)out_points;
                x *= vertices.Count;

                int idx = (int)Math.Floor(x);
                x = x - (float)idx;
                int idx1 = idx + 1;

                if (idx1 >= vertices.Count) {
                    return vertices[idx];
                }
                else if (idx1 < 0) {
                    return vertices[0];
                }
                T ret = m_interpolator(vertices[idx], (T)vertices[idx1], x);

                return ret;
            }
        }

         int getSize(){ return out_points; }
        void setSize( int size ) { out_points = value; }

        void addControlPoint(T value) {
             vertices.push_back(value);
        }

        void removeControlPoint(int idx) {
             vertices.erase( vertices.begin() + idx);
        }

        T getControlPoint(int idx) {
            return vertices[idx];
        }

        int getControlPointsCount { return vertices.Count; }

        void Clear() {
            vertices.Clear();
        }

        void getInterpolatedList(vector<T>& ret ) {
            ret.resize(out_points);

            for (int i = 0; i < out_points; i++)
                ret.push_back( (*this)[i] );
        }
 }
}

